#pragma once
#include <stdint.h>
#include "Creature.h"
#include "Common/Timer/TimerAxis.h"
#include "Common/Event/Event.h"
#include "Common/Item/ItemMgr.h"
#include "Common/PackageDefine.h"
#include "Common/DuplicateDefine.h"
#include "Common/AchievementDefine.h"

//#pragma warning(disable : 4100)

class Part : public IEventExecuteSink, public ITimerHandler
{
protected:
	Creature *m_pMaster;
	uint32_t m_partType;
public:
	Part();
	virtual ~Part();
	//******************part调用生物接口******************
	//生物init调用
	virtual bool Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB = nullptr);
	//生物uint调用
	virtual bool UnInit();
	//清除生物部件数据
	virtual bool ClearState();

	//部件类型
	uint32_t getPartType();
	//生物存储DB部件入口
	virtual bool SaveDB(CharacterDBInfo& characterDB) { return true; };
	//生物登入同步客户度数据入口
	virtual bool SynOnLogin() { return true; }
	virtual bool SynOnLogin(PlayerClientInfo& playerInfo){ return true; };
	//生物登出入口
	virtual void SynLogout(){};
	//生物切换逻辑节点
	virtual void BeforeChangeLogic(){};
	//生物切换逻辑节点
	virtual void OnChangeLogic() {};
	//客户端消息入口
	virtual bool OnMsgHandle(uint32_t cmd, const char* data, uint32_t len) = 0; 
	//时间戳封装 INFINITY_CALL  调用无限次
	bool SetTimedo(uint32_t timeId, uint64_t iterval, uint32_t callcount = INFINITY_CALL);
	void KillTimedo(uint32_t timeId);
	void KillAllTimerdo();
	//生物update
	virtual void Update(uint64_t tick) {};
	//生物升级客户端同步
	virtual void SynCreatureLevUp(CreaturesLevUp& clientLevInfo){};

	//事件和时间调用的直接用下面的就行了
	virtual void OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen) { }
	virtual void OnTimer(uint32_t nTimerId){};
	//************************************************

	//******************生物调用部件接口******************
	//新加技能
	virtual bool AddSkill(uint32_t skillId, uint32_t lev, uint64_t cd = 0, uint32_t priority = 0, bool calcFightPower = true, bool isNoticeClient = true) { return true; }
	//移除技能
	virtual bool RemoveSkill(uint32_t SkillId) { return true; }

	//******************移动接口:直接调用Creature里面的接口就可以了***********
	//1、知道场景Id调用场景Id sceneId
	//2、如果不知道场景Id, sceneId=0, 调用mapId(策划表id)
	virtual bool TransScene(uint32_t scenceId, Point3<float>& dstPos, uint32_t mapId = 0){ return true; }; //强制传送(场景内传送、切场景传送)
	virtual bool MoveTo(Point3<float> dstPos){ return true; };														   //移动
	virtual void StopMove(){};																			   //停止当前移动,广播告诉其他人
	//********************************************


	/////////////////////////////// 背包接口///////////////////////////////////////////
	//获取指定物品数量
	virtual int32_t GetItemNum(uint32_t nItemID, int32_t &nUnBindNum, int32_t &nBindNum){ return 0; }
	//使用物品(与背包无关的使用)
	virtual void Use(CItemBase *pItem) {};
	//是否存在物品
	virtual bool HasItem(LIST_ITEM &lstItem){ return false; }
	//移除物品
	virtual bool RemoveItem(uint32_t nItemID, int32_t nNum, SItemSourceParam &sourceParam, int8_t byBind = (int8_t)EBindState::EBindState_all){ return false; };
	//移除物品
	virtual bool RemoveItem(LIST_ITEM &lstItem, SItemSourceParam &sourceParam) { return false; }
	//移除物品 index,num sourceParam : 物品移除来源（暂时没有）
	virtual bool RemoveItemByIndex(uint16_t nIndex, int32_t nNum, SItemSourceParam &sourceParam){ return false; };
	//移除物品 index-num
	virtual bool RemoveItem(MAP_UINT16_INT32 &mapIndexItem, SItemSourceParam &sourceParam) { return false; }
	//移除穿戴装备 index
	virtual bool RemovePlayerEquip(SET_UINT8 &setIdx){ return false; };
	//是否能添加物品
	virtual bool CanAddItem(LIST_ITEM &lstItem) { return false; }
	//能否添加物品
	virtual bool CanAddItem(VEC_ITEM_PROTO_EX &vecProtoItemsEx) { return false; }
	//添加物品
	virtual bool AddItem(uint32_t nItemID, int32_t nNum, SItemSourceParam &sourceParam, int8_t byBind = (int8_t)EBindState::EBindState_no){ return false; }
	//添加物品 sourceParam : 物品来源（暂时没有）
	virtual bool AddItem(LIST_ITEM &lstItem, SItemSourceParam &sourceParam, bool update = true) { return false; }
	//添加物品
	virtual bool AddItem(VEC_ITEM_PROTO &vecProtoItems, SItemSourceParam &sourceParam, bool update = true){ return false; }
	//添加物品 sourceParam : 物品来源（暂时没有）
	virtual bool AddItem(VEC_ITEM_PROTO_EX &vecProtoItemsEx, SItemSourceParam &sourceParam, bool update = true){ return false; };
	//添加物品 sourceParam : 物品来源（暂时没有） vecProtoItemsOut:传出参数，外部需要的物品数据
	virtual bool AddItem(VEC_ITEM_PROTO_EX &vecProtoItemsEx, VEC_ITEM_PROTO_EX &vecProtoItemsOut, SItemSourceParam &sourceParam, bool update = true){ return false; };
	//清空背包所有物品
	virtual bool ClearPackage() { return false; };
	//扩展背包
	virtual int32_t Expand(uint16_t nNum) { return RET_FAIL; };
	//扩展仓库
	virtual int32_t ExpandStorage(uint16_t nNum) { return RET_FAIL; }
	//获取装备信息
	virtual VEC_PLAYER_EQUIP *GetPlayerEquip() { return nullptr; }
	//获取索引位置物品
	virtual const CItemBase *GetItem(uint16_t nIndex) { return nullptr; }
	//获取物品（根据tem.xlsx 表中 subType 字段 获取物品, 只返回找到的第一个物品）
	virtual const CItemBase *GetItemByType(int32_t itemSubType){ return nullptr; };
	//移除所有指定类型的物品（根据 tem.xlsx 表中 subType 字段 移除物品）
	virtual bool RemoveAllByType(int32_t itemSubType, SItemSourceParam &sourceParam) { return false; };
	//获取所有可掉落的穿戴装备
	virtual void GetAllCanDropEquip(VEC_COMMON_ITEM &vecEquip) {};
	//获取所有可掉落的背包物品
	virtual void GetAllCanDropPackage(VEC_COMMON_ITEM &vecPakcage){};
	//获取外观
	virtual void GetFacade(uint32_t &clothesId, uint32_t &weaponId, uint32_t &wingId) {};
	//激活 nIdx:物品索引，bActive ： true:激活，false:取消激活
	virtual int32_t Active(uint16_t nIdx) { return RET_FAIL; };
	//取消激活
	virtual void UnActive() {};
	//设置跑商资金 itemSubType:物品子类型 （根据tem.xlsx 表中 subType 字段， 只设置找到的第一个物品 ）
	virtual bool SetRunBusiness(uint16_t nIndex, int32_t fund) { return nullptr; };
	//添加打造的物品
	virtual bool AddItemByMake(uint32_t nItemID, const char *szMaker, SItemCond &itemCond, SItemSourceParam &sourceParam, int8_t byBind = (int8_t)EBindState::EBindState_no){ return false; };
	//使用物品 nIndex:物品所在背包索引,nNum:使用的数量,protoArg:使用物品需要的参数
	virtual int32_t UseItem(uint16_t nIndex, int32_t nNum, UseItemArgProto &protoArg){ return RET_FAIL; };
	//星魂传送
	virtual int32_t OnStarSoul(int16_t nIndex) { return false; }
	//星魂传送返回
	virtual void OnStarSoulRsp(int32_t ret, int16_t nIndex) {};
	//使用时装
	virtual int32_t ActiveFashion(int32_t nItemID, uint32_t fashionId) { return false; }
	/////////////////////////////////// 副本接口 ///////////////////////////////////////
	//副本完成
	virtual void DuplicateFinish(DuplicateResult &result){};
	//通知离开副本
	virtual void NotifyLeave(uint32_t nDuplicateID, int8_t byKeyType){};
	//准备进入副本
	virtual int32_t PrepareEnter(uint32_t duplicateId, uint32_t sceneId, int8_t keyType, uint64_t keyValue){ return RET_FAIL; };
	//通知进入副本
	virtual bool NotifyEnter(uint32_t duplicateId, uint32_t sceneId,uint32_t bornId = 0){ return false; };
	//通知进入副本失败
	virtual void NotifyEnterFailed(uint32_t nDuplicateID, int32_t retcode){};
	//通知进入成功
	virtual void NotifyEnterSuccess(DupEnterParam &enterParam) {};
	//是否能进副本
	virtual int32_t CanEnterDup(uint32_t dupId) { return RET_FAIL; };
	//重连
	virtual void NotifyReconnect(DupEnterParam &enterParam){};
	//////////////////////////////////////////////////////////////////////////

	/////////////////////////////////// 成就接口 ///////////////////////////////////////
	//功能接口
	//更新成就,其他系统统一调用接口
	virtual void UpdateAchievement(AchievementParameterInfo& achievementParameter){};
	//////////////////////////////////////////////////////////////////////////

	////////////////////////////////// 每日每周刷新接口 ///////////////////////////////////
	virtual bool DailyUpdate(uint64_t unixSec){ return true; }
	virtual bool WeekUpdate(uint64_t unixSec){ return true; }
	////////////////////////////////// 每日零点 每周一零点 刷新接口 ///////////////////////////////////
	virtual bool DailyZeroUpdate(uint64_t unixSec){ return true; }
	virtual bool WeekZeroUpdate(uint64_t unixSec){ return true; }

	///////////////////////////////////////////////////////////////////////////////////

	//充值
	virtual uint32_t PayRmb() { return 0; }

public:
	///////////////////////////////buff 接口///////////////////////////////////////////
	//buff 修改 玩家承受的伤害
	virtual void BuffEffect_AddExtraDamage(Creature* pBeAttacked, uint32_t skillId, int32_t &damage) { }
	virtual void BuffEffect_ReduceDamage(Creature* pAttack, uint32_t skillId, int32_t &damage) { }
	virtual bool BuffEffect_HasBuffBag(uint32_t stateBagId) { return false; }
};
